package com.zshan.clinic.admin.service.config;

import com.zshan.clinic.admin.entity.vo.ClinicPrintConfigGroupVo;
import com.zshan.clinic.admin.entity.vo.ClinicPrintConfigVo;
import com.zshan.clinic.admin.mapper.config.SpecClinicPrintConfigMapper;
import com.zshan.clinic.admin.service.clinic.ClinicEmpService;
import com.zshan.clinic.admin.service.clinic.ClinicInfoService;
import com.zshan.clinic.common.enums.PrintCategoryEnum;
import com.zshan.clinic.common.enums.PrintTypeEnum;
import com.zshan.clinic.common.enums.YesOrNoEnum;
import com.zshan.clinic.common.exception.BusinessFailException;
import com.zshan.clinic.common.util.page.PageInfo;
import com.zshan.clinic.common.util.page.PageUtils;
import com.zshan.clinic.common.util.string.StringUtil;
import com.zshan.clinic.database.dao.ClinicPrintConfigMapper;
import com.zshan.clinic.database.model.ClinicEmp;
import com.zshan.clinic.database.model.ClinicInfo;
import com.zshan.clinic.database.model.ClinicPrintConfig;
import com.zshan.clinic.database.model.ClinicPrintConfigExample;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 打印设置
 */
@Service
@Slf4j
public class PrintConfigService {

    @Autowired
    private ClinicPrintConfigMapper clinicPrintConfigMapper;

    @Autowired
    private ClinicInfoService clinicInfoService;

    @Autowired
    private ClinicEmpService clinicEmpService;

    @Autowired
    private SpecClinicPrintConfigMapper specClinicPrintConfigMapper;

    /**
     * 获取诊所的打印配置
     * @param clinicId
     * @param printCategory
     * @param printType
     * @return
     */
    /**
     * 获取诊所的打印配置
     * @param clinicId 诊所ID
     * @param printCategory 打印分类（如文档/小票）
     * @param printTypeList 打印类型列表
     * @return
     */
    public ClinicPrintConfigVo getConfigByCategoryAndType(Long clinicId, String printCategory, List<String> printTypeList) {
        // 获取诊所打印配置
        ClinicPrintConfigGroupVo clinicPrintConfigGroupVo = getPrintConfigList(clinicId);
        List<ClinicPrintConfigVo> clinicPrintConfigVoList = null;
        // 分类
        if (PrintCategoryEnum.DOCUMENT.getValue().equals(printCategory)) {
            clinicPrintConfigVoList = clinicPrintConfigGroupVo.getDocumentList();
        } else if (PrintCategoryEnum.RECEIPT.getValue().equals(printCategory)) {
            clinicPrintConfigVoList = clinicPrintConfigGroupVo.getReceiptList();
        }
        // 过滤
        if (!CollectionUtils.isEmpty(clinicPrintConfigVoList) && !CollectionUtils.isEmpty(printTypeList)) {
            return clinicPrintConfigVoList.stream()
                    .filter(vo -> printTypeList.contains(vo.getPrintType()))
                    .findFirst()
                    .orElse(null);
        }
        return null;
    }


    /**
     * 获取诊所打印设置
     * @param clinicId
     * @return
     */
    public ClinicPrintConfigGroupVo getPrintConfigList(Long clinicId){
        ClinicInfo clinicInfo = clinicInfoService.getClinicById(clinicId);
        if(clinicInfo == null){
            throw new BusinessFailException("诊所不存在");
        }
        ClinicEmp clinicAdmin = clinicEmpService.getClinicAdmin(clinicId);
        if(clinicAdmin == null){
            throw new BusinessFailException("管理员不存在");
        }
        List<ClinicPrintConfigVo> printConfigVoList = specClinicPrintConfigMapper.getPrintConfigList(clinicId,clinicInfo.getClinicName(),clinicInfo.getAddress(),clinicAdmin.getPhone());
        if(CollectionUtils.isEmpty(printConfigVoList)){
            return ClinicPrintConfigGroupVo.build();
        }
        ClinicPrintConfigGroupVo groupVo = new ClinicPrintConfigGroupVo();
        groupVo.setDocumentList(printConfigVoList.stream()
                .filter(f -> PrintCategoryEnum.DOCUMENT.getValue().equals(f.getPrintCategory()))
                .collect(Collectors.toList()));
        groupVo.setReceiptList(printConfigVoList.stream()
                .filter(f -> PrintCategoryEnum.RECEIPT.getValue().equals(f.getPrintCategory()))
                .collect(Collectors.toList()));
        return groupVo;
    }

    /**
     * 分页查询诊所打印设置
     * @param printCategory 打印分类（精确匹配）
     * @param pageNo 页码
     * @param pageSize 每页条数
     * @return 分页结果
     */
    public PageInfo<ClinicPrintConfig> getPrintConfigListByCondition(String printCategory, String printType,Integer pageNo, Integer pageSize) {
        ClinicPrintConfigExample example = new ClinicPrintConfigExample();
        ClinicPrintConfigExample.Criteria criteria = example.createCriteria();
        if (StringUtil.isNotBlank(printCategory)) {
            criteria.andPrintCategoryEqualTo(printCategory);
        }
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        Long totalCount = clinicPrintConfigMapper.countByExample(example);
        if (totalCount == null || totalCount == 0) {
            return PageInfo.build();
        }
        example.setOffset(PageUtils.getOffset(pageNo, pageSize));
        example.setLimit(pageSize);
        example.setOrderByClause("create_time desc");
        List<ClinicPrintConfig> list = clinicPrintConfigMapper.selectByExample(example);
        return new PageInfo<>(totalCount, list);
    }

    /**
     * 保存全部
     * @param clinicPrintConfig
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveAllPrintConfig(ClinicPrintConfig clinicPrintConfig){
        validatePrintConfig(clinicPrintConfig);
        //先删除历史的
        deletePrintConfigBatch(clinicPrintConfig.getClinicId(),clinicPrintConfig.getCreateUserId(),clinicPrintConfig.getCreateBy());
        //保存全部
        addPrintConfigBatch(clinicPrintConfig);
    }

    /**
     * 批量添加
     * @param clinicPrintConfig
     */
    @Transactional(rollbackFor = Exception.class)
    public void addPrintConfigBatch(ClinicPrintConfig clinicPrintConfig) {
        List<ClinicPrintConfig> configList = new ArrayList<>();
        List<Map> printTypeList = PrintTypeEnum.allToMap();
        Date createTime = new Date();
        for(Map printTypeMap : printTypeList){
            ClinicPrintConfig config = new ClinicPrintConfig();
            config.setPrintCategory((String) printTypeMap.get("categoryCode"));
            config.setPrintType((String) printTypeMap.get("value"));
            config.setTitle(clinicPrintConfig.getTitle());
            config.setAddress(clinicPrintConfig.getAddress());
            config.setPhone(clinicPrintConfig.getPhone());
            config.setClinicId(clinicPrintConfig.getClinicId());
            config.setIsEnabled(YesOrNoEnum.YES.getValue());
            config.setIsDelete(YesOrNoEnum.NO.getValue());
            config.setCreateUserId(clinicPrintConfig.getCreateUserId());
            config.setCreateBy(clinicPrintConfig.getCreateBy());
            config.setCreateTime(createTime);
            configList.add(config);
        }
        specClinicPrintConfigMapper.addPrintConfigBatch(configList);
    }


    /**
     * 批量删除
     * @param clinicId
     * @param updateUserId
     * @param updateBy
     */
    @Transactional(rollbackFor = Exception.class)
    public void deletePrintConfigBatch(Long clinicId,Long updateUserId,String updateBy) {
        ClinicPrintConfigExample example = new ClinicPrintConfigExample();
        ClinicPrintConfigExample.Criteria criteria = example.createCriteria();
        criteria.andClinicIdEqualTo(clinicId);
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        ClinicPrintConfig clinicPrintConfig = new ClinicPrintConfig();
        clinicPrintConfig.setIsDelete(YesOrNoEnum.YES.getValue());
        clinicPrintConfig.setUpdateUserId(updateUserId);
        clinicPrintConfig.setUpdateBy(updateBy);
        clinicPrintConfig.setUpdateTime(new Date());
        clinicPrintConfigMapper.updateByExampleSelective(clinicPrintConfig,example);
    }

    /**
     * 保存
     * @param clinicPrintConfig
     */
    @Transactional(rollbackFor = Exception.class)
    public void savePrintConfig(ClinicPrintConfig clinicPrintConfig){
        validatePrintConfig(clinicPrintConfig);
        ClinicPrintConfig dbClinicPrintConfig = getConfigByCategory(clinicPrintConfig.getClinicId(),clinicPrintConfig.getPrintCategory(),clinicPrintConfig.getPrintType());
        if(dbClinicPrintConfig == null){
            addPrintConfig(clinicPrintConfig);
        }else {
            dbClinicPrintConfig.setTitle(clinicPrintConfig.getTitle());
            dbClinicPrintConfig.setAddress(clinicPrintConfig.getAddress());
            dbClinicPrintConfig.setPhone(clinicPrintConfig.getPhone());
            dbClinicPrintConfig.setUpdateUserId(clinicPrintConfig.getCreateUserId());
            dbClinicPrintConfig.setUpdateBy(clinicPrintConfig.getCreateBy());
            updatePrintConfig(dbClinicPrintConfig);
        }
    }


    /**
     * 批量查询打印设置
     * @param clinicId
     * @param printCategory
     * @param printTypeList
     * @return
     */
    public List<ClinicPrintConfig> getConfigByCategoryList(Long clinicId,String printCategory,List<String> printTypeList){
        ClinicPrintConfigExample example = new ClinicPrintConfigExample();
        ClinicPrintConfigExample.Criteria criteria = example.createCriteria();
        criteria.andClinicIdEqualTo(clinicId);
        criteria.andPrintCategoryEqualTo(printCategory);
        criteria.andPrintTypeIn(printTypeList);
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        List<ClinicPrintConfig> printConfigList = clinicPrintConfigMapper.selectByExample(example);
        return printConfigList;
    }

    public ClinicPrintConfig getConfigByCategory(Long clinicId,String printCategory,String printType){
        ClinicPrintConfigExample example = new ClinicPrintConfigExample();
        ClinicPrintConfigExample.Criteria criteria = example.createCriteria();
        criteria.andClinicIdEqualTo(clinicId);
        criteria.andPrintCategoryEqualTo(printCategory);
        criteria.andPrintTypeEqualTo(printType);
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        List<ClinicPrintConfig> printConfigList = clinicPrintConfigMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(printConfigList)){
            return null;
        }
        return printConfigList.get(0);
    }

    /**
     * 添加诊所打印设置
     * @param clinicPrintConfig 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void addPrintConfig(ClinicPrintConfig clinicPrintConfig) {
        clinicPrintConfig.setIsDelete(YesOrNoEnum.NO.getValue());
        clinicPrintConfig.setIsEnabled(YesOrNoEnum.YES.getValue());
        clinicPrintConfig.setCreateTime(new Date());
        clinicPrintConfigMapper.insertSelective(clinicPrintConfig);
    }

    /**
     * 校验打印配置参数
     * @param clinicPrintConfig 实体
     */
    public void validatePrintConfig(ClinicPrintConfig clinicPrintConfig) {
        // 添加必要字段校验，如 printCategory 非空等
        if (StringUtil.isBlank(clinicPrintConfig.getPrintCategory())) {
            throw new BusinessFailException("打印类别不能为空");
        }
        if(!PrintCategoryEnum.isValue(clinicPrintConfig.getPrintCategory())){
            throw new BusinessFailException("打印类别错误");
        }
        if (StringUtil.isBlank(clinicPrintConfig.getPrintType())) {
            throw new BusinessFailException("打印类型不能为空");
        }
        if(!PrintTypeEnum.isValue(clinicPrintConfig.getPrintType())){
            throw new BusinessFailException("打印类别错误");
        }
        if (StringUtil.isBlank(clinicPrintConfig.getTitle())) {
            throw new BusinessFailException("标题不能为空");
        }
        if (StringUtil.isBlank(clinicPrintConfig.getAddress())) {
            throw new BusinessFailException("地址不能为空");
        }
        if (StringUtil.isBlank(clinicPrintConfig.getPhone())) {
            throw new BusinessFailException("电话不能为空");
        }
    }

    /**
     * 根据ID获取打印设置详情
     * @param configId 主键
     * @return 实体
     */
    public ClinicPrintConfig getPrintConfigById(Long configId) {
        if (StringUtil.isBlank(configId)) {
            return null;
        }
        ClinicPrintConfig config = clinicPrintConfigMapper.selectByPrimaryKey(configId);
        if (config == null || YesOrNoEnum.YES.getValue().equals(config.getIsDelete())) {
            return null;
        }
        return config;
    }

    /**
     * 修改诊所打印设置
     * @param clinicPrintConfig 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePrintConfig(ClinicPrintConfig clinicPrintConfig) {
        clinicPrintConfig.setUpdateTime(new Date());
        clinicPrintConfigMapper.updateByPrimaryKeySelective(clinicPrintConfig);
    }

    /**
     * 删除诊所打印设置（逻辑删除）
     * @param clinicPrintConfig 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void deletePrintConfig(ClinicPrintConfig clinicPrintConfig) {
        ClinicPrintConfig dbConfig = getPrintConfigById(clinicPrintConfig.getConfigId());
        if (dbConfig == null) {
            throw new BusinessFailException("打印设置不存在");
        }
        dbConfig.setIsDelete(YesOrNoEnum.YES.getValue());
        dbConfig.setUpdateUserId(clinicPrintConfig.getUpdateUserId());
        dbConfig.setUpdateBy(clinicPrintConfig.getUpdateBy());
        dbConfig.setUpdateTime(new Date());
        clinicPrintConfigMapper.updateByPrimaryKeySelective(dbConfig);
    }

    /**
     * 启用打印设置
     * @param clinicPrintConfig 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void enablePrintConfig(ClinicPrintConfig clinicPrintConfig) {
        ClinicPrintConfig dbConfig = getPrintConfigById(clinicPrintConfig.getConfigId());
        if (dbConfig == null) {
            throw new BusinessFailException("打印设置不存在");
        }
        if (YesOrNoEnum.YES.getValue().equals(dbConfig.getIsEnabled())) {
            return;
        }
        dbConfig.setIsEnabled(YesOrNoEnum.YES.getValue());
        dbConfig.setUpdateUserId(clinicPrintConfig.getUpdateUserId());
        dbConfig.setUpdateBy(clinicPrintConfig.getUpdateBy());
        dbConfig.setUpdateTime(new Date());
        clinicPrintConfigMapper.updateByPrimaryKeySelective(dbConfig);
    }

    /**
     * 停用打印设置
     * @param clinicPrintConfig 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void disablePrintConfig(ClinicPrintConfig clinicPrintConfig) {
        ClinicPrintConfig dbConfig = getPrintConfigById(clinicPrintConfig.getConfigId());
        if (dbConfig == null) {
            throw new BusinessFailException("打印设置不存在");
        }
        if (YesOrNoEnum.NO.getValue().equals(dbConfig.getIsEnabled())) {
            return;
        }
        dbConfig.setIsEnabled(YesOrNoEnum.NO.getValue());
        dbConfig.setUpdateUserId(clinicPrintConfig.getUpdateUserId());
        dbConfig.setUpdateBy(clinicPrintConfig.getUpdateBy());
        dbConfig.setUpdateTime(new Date());
        clinicPrintConfigMapper.updateByPrimaryKeySelective(dbConfig);
    }

}
